﻿Namespace Services
    Public Class ServiceBroker
        'Credit for the original C# version goes to Team MediaPortal
        Implements IDisposable
        Public ReadOnly Services As Dictionary(Of Type, Object)
        <ThreadStatic()> _
        Private Shared Current As ServiceBroker
        Public Property ServiceInstance() As ServiceBroker
            Get
                Return Current
            End Get
            Set(ByVal value As ServiceBroker)
                Current = value
            End Set
        End Property
        Private Sub AddService(Of T)(ByVal Service As T)
            Services(GetType(T)) = Service
        End Sub
        Private Function GetService(Of T)() As T
            Dim Type As Type = GetType(T)
            If Services.ContainsKey(Type) Then
                Return DirectCast(Services(Type), T)
            Else
                Throw New NullReferenceException(String.Format("Service of type {0} has not yet been registered, and therefore is not available for usage in the program.", Type.ToString))
            End If
        End Function
        Public Function [Get](Of T)() As T
            Return GetService(Of T)()
        End Function
        Public Sub Add(Of T)(ByVal Service As T)
            ServiceInstance.AddService(Of T)(Service)
        End Sub
        Public Sub New()
            ServiceInstance = Me
            Services = New Dictionary(Of Type, Object)
        End Sub
#Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
        Private disposedValue As Boolean = False        ' To detect redundant calls
        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: free other state (managed objects).
                End If

                ' TODO: free your own state (unmanaged objects).
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub
#End Region
    End Class
End Namespace